package com.haisen.core.utils;

import com.alibaba.fastjson.JSON;
import com.haisen.service.impl.WebSocketService;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.SqlSession;
import org.apache.zookeeper.util.SecurityUtils;
import org.springframework.util.StringUtils;

import java.lang.reflect.ParameterizedType;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 拟设计成通用的批量插入类
 * 通过websocket将执行进度通知前端页面
 */
@Slf4j
//@Data
public class InsertBatch<T> {
/*
    @Autowired
    WebSocketService webSocketService;
    private  static  InsertBatch insertBatch;
    //通过@PostConstruct实现初始化bean之前进行的操作
    @PostConstruct
    public void init() {
        insertBatch = this;
        insertBatch.webSocketService = this.webSocketService;
        // 初使化时将已静态化的testService实例化
    }*/
    private static WebSocketService webSocketService;


    public Class<T> getTClass()
    {
        Class<T> tClass = (Class<T>)((ParameterizedType)getClass().getGenericSuperclass()).getActualTypeArguments()[0];
        return tClass;
    }
     public static Integer lineNumber = 0;
     public static  Integer insertedNumer = 0;
    Map<String,String> map = new HashMap<>();


    public void insertBatch(SqlSession sqlSession,MyMapper<T> myMapper,List<T> list) {
        String clzName = "";
        int batchCount = 200;// 每批commit的个数
        int batchLastIndex = batchCount;// 每批最后一个的下标
        //设置保存的条数
        lineNumber = list.size();
        map.put("status","开始保存数据");
        map.put("total",String.valueOf(lineNumber));
        map.put("curr",String.valueOf(0));
        //String username = (String) SecurityUtils.getSubject().getPrincipal();
        String username = "";
        if (StringUtils.isEmpty(username)){
            username = "admin";
        }
        /**
         * 通过appcation来获取bean，用@Autowired无法获取注入
         * 本质原因：spring管理的都是单例（singleton），和 websocket （多对象）相冲突。
         */
         webSocketService = SpringBeanUtil.getBean(WebSocketService.class);
        webSocketService.SendMessageToUser(username,JSON.toJSONString(map));
        // WebSocket.sendMessage(JSON.toJSONString(map));
        try {
            for (int index = 0; index < list.size(); ) {
                if (batchLastIndex >= list.size()) {
                    batchLastIndex = list.size();
                    list.subList(index, batchLastIndex).stream()
                            .map(o -> {
                              //  log.info("插入数据 ={}",JSON.toJSONString(o));
                                return myMapper.insertSelective(o);
                            }).collect(Collectors.toList());
                    //设置已保存的数量
                    insertedNumer += batchLastIndex-index;
                    map.put("status","保存数据");
                    map.put("total",String.valueOf(lineNumber));
                    map.put("curr",String.valueOf(insertedNumer));
                    webSocketService.SendMessageToUser(username,JSON.toJSONString(map));
                    log.info("发送消息to：{},msg={}",username,JSON.toJSONString(map));
                    sqlSession.commit();
                    sqlSession.clearCache();
                    break;// 数据插入完毕，退出循环
                } else {
                    log.info("读取数据列表：从{}到{}", index, batchLastIndex);
                    list.subList(index, batchLastIndex).stream()
                            .map(o -> {
                               // log.info("插入数据 ={}",JSON.toJSONString(o));
                                return myMapper.insertSelective(o);
                            }).collect(Collectors.toList());
                    //设置已保存的数量
                    insertedNumer += batchLastIndex-index;
                    map.put("status","保存数据");
                    map.put("total",String.valueOf(lineNumber));
                    map.put("curr",String.valueOf(insertedNumer));
                   webSocketService.SendMessageToUser(username,JSON.toJSONString(map));
                    log.info("发送消息to：{},msg={}",username,JSON.toJSONString(map));
                    index = batchLastIndex;// 设置下一批下标
                    sqlSession.commit();
                    sqlSession.clearCache();
                }
                log.info("插入了={}条，",insertedNumer);
                //导入进度
                batchLastIndex = index + (batchCount - 1);
            }
        } finally {
            sqlSession.close();
        }

    }

}
